package se.sics.drsm;

import org.apache.log4j.PropertyConfigurator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import se.sics.drsm.components.DRSMNode;
import se.sics.drsm.inits.NodeInit;
import se.sics.drsm.model.DRSMConfiguration;
import se.sics.drsm.model.SONConfiguration;
import se.sics.drsm.overlay_address.key.NumericRingKey;
import se.sics.drsm.ports.drsm.NodePort;
import se.sics.drsm.ports.drsm.events.DRSMJoinRing;
import se.sics.drsm.ports.drsm.events.DRSMLookupRequest;
import se.sics.kompics.Component;
import se.sics.kompics.ComponentDefinition;
import se.sics.kompics.Kompics;
import se.sics.kompics.address.Address;
import se.sics.kompics.launch.Topology;
import se.sics.kompics.network.Network;
import se.sics.kompics.network.mina.MinaNetwork;
import se.sics.kompics.network.mina.MinaNetworkInit;
import se.sics.kompics.p2p.bootstrap.BootstrapConfiguration;
import se.sics.kompics.p2p.fd.ping.PingFailureDetectorConfiguration;
import se.sics.kompics.p2p.monitor.chord.server.ChordMonitorConfiguration;

import java.io.IOException;

public class DRSMContainerMain extends ComponentDefinition {

    static {
        PropertyConfigurator.configureAndWatch("log4j.properties");
    }

    private static int selfId;
    Topology topology = Topology.load(System.getProperty("topology"), selfId);

    private static final Logger logger = LoggerFactory
            .getLogger(DRSMContainerMain.class);

    public static void main(String[] args) {
        selfId = Integer.parseInt(args[0]);
        Kompics.createAndStart(DRSMContainerMain.class, 8);

    }

    public DRSMContainerMain() throws IOException {

        Address self = topology.getSelfAddress();
        // Components
        Component DRSMNode = create(DRSMNode.class);
        Component network = create(MinaNetwork.class);

        // TODO: Use a config class
        BootstrapConfiguration bconfiguration; // Should be default values
        bconfiguration = BootstrapConfiguration.load("bootstrap.properties");

        SONConfiguration sonConfiguration;
        sonConfiguration = SONConfiguration.load("chord.properties");

        DRSMConfiguration drsmConfiguration;
        drsmConfiguration = DRSMConfiguration.load("drsm.properties");

        PingFailureDetectorConfiguration failureDetectorConfiguration = null;
        failureDetectorConfiguration = PingFailureDetectorConfiguration.load("failure_detector.properties");

        ChordMonitorConfiguration chordMonitorConfiguration;
        chordMonitorConfiguration = ChordMonitorConfiguration.load("chord_monitor.properties");

        // firing inits
        NodeInit nodeInit = new NodeInit
                (self, bconfiguration, chordMonitorConfiguration, sonConfiguration, failureDetectorConfiguration);
        trigger(nodeInit, DRSMNode.getControl());
        trigger(new MinaNetworkInit(self), network.getControl());

        // Connections between components
        connect(DRSMNode.getNegative(Network.class),
                network.getPositive(Network.class));

        // TODO tests events
        Long key = (long) selfId;
        DRSMJoinRing joinEvent = new DRSMJoinRing(new NumericRingKey(key));
        trigger(joinEvent, DRSMNode.getPositive(NodePort.class));
        System.err.println("ring id" + key);

        Long lkupkey = (long) selfId + 2;
        DRSMLookupRequest lkupReq = new DRSMLookupRequest(new NumericRingKey(lkupkey), null, false);
        trigger(lkupReq, DRSMNode.getPositive(NodePort.class));


    }
}